﻿using MapsterMapper;

namespace OpenAdmin.Application.Services;

/// <summary>
/// 服务基类
/// </summary>
public class ServiceBase
{
    /// <summary>
    /// 
    /// </summary>
    protected readonly IMapper _mapper;
    /// <summary>
    /// ctor
    /// </summary>
    public ServiceBase()
    {
        _mapper = App.HttpContext.RequestServices.GetService<IMapper>();
    }

    private UserIdentity _userIdentity;
    /// <summary>
    /// 用户信息
    /// </summary>
    protected UserIdentity UserIdentity
    {
        get
        {
            if (_userIdentity == null)
            {
                var claims = App.HttpContext.User.Claims;
                _userIdentity = new UserIdentity();
                if (int.TryParse(claims.SingleOrDefault(c => c.Type == ClaimTypeConsts.UserId)?.Value, out int userId))
                {
                    _userIdentity.UserId = userId;
                }
                _userIdentity.UserName = claims.SingleOrDefault(c => c.Type.Equals(nameof(_userIdentity.UserName)))?.Value;
                _userIdentity.RealName = claims.SingleOrDefault(c => c.Type.Equals(nameof(_userIdentity.RealName)))?.Value;
                _userIdentity.Avatar = claims.SingleOrDefault(c => c.Type.Equals(nameof(_userIdentity.Avatar)))?.Value;
                var hasSuperAdminString = claims.SingleOrDefault(c => c.Type.Equals(ClaimTypeConsts.HasSuperAdmin))?.Value;
                _ = bool.TryParse(hasSuperAdminString, out var hasSuperAdmin);
                _userIdentity.HasSuperAdmin = hasSuperAdmin;
            }
            return _userIdentity;
        }
    }

    /// <summary>
    /// 执行事务
    /// </summary>
    /// <param name="context"></param>
    /// <param name="action"></param>
    /// <returns></returns>
    public async static Task ExecuteTransactionAsync(DbContext context, Func<Task> action)
    {
        var strategy = context.Database.CreateExecutionStrategy();
        await strategy.ExecuteAsync(async () =>
        {
            using (var transaction = context.Database.BeginTransaction())
            {
                await action();
                transaction.Commit();
            }
        });
    }
}
